{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true,
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import h5py\n",
    "import matplotlib.pyplot as plt\n",
    "import testCases #参见资料包，或者在文章底部copy\n",
    "from dnn_utils import sigmoid, sigmoid_backward, relu, relu_backward #参见资料包\n",
    "import lr_utils #参见资料包，或者在文章底部copy\n",
    "# 指定随机种子\n",
    "np.random.seed(1)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "outputs": [],
   "source": [
    "def initialize_parameters(n_x, n_h, n_y):\n",
    "    '''\n",
    "    此函数是为了初始化两层网络参数而使用的函数。\n",
    "    参数：\n",
    "        n_x - 输入层节点数量\n",
    "        n_h - 隐藏层节点数量\n",
    "        n_y - 输出层节点数量\n",
    "\n",
    "    返回：\n",
    "        parameters - 包含你的参数的python字典：\n",
    "            W1 - 权重矩阵,维度为（n_h，n_x）\n",
    "            b1 - 偏向量，维度为（n_h，1）\n",
    "            W2 - 权重矩阵，维度为（n_y，n_h）\n",
    "            b2 - 偏向量，维度为（n_y，1）\n",
    "    '''\n",
    "    # 乘以0.01是防止梯度下降缓慢\n",
    "    W1 = np.random.randn(n_h, n_x) * 0.01\n",
    "    b1 = np.zeros((n_h, 1))\n",
    "    W2 = np.random.randn(n_y, n_h) * 0.01\n",
    "    b2 = np.zeros((n_y, 1))\n",
    "\n",
    "    # 使用断言来确保我的数据格式是正确的\n",
    "    assert(W1.shape == (n_h ,n_x))\n",
    "    assert(b1.shape == (n_h, 1))\n",
    "    assert(W2.shape == (n_y, n_h))\n",
    "    assert(b2.shape == (n_y, 1))\n",
    "\n",
    "    parameters = {\n",
    "        \"W1\": W1,\n",
    "        \"b1\": b1,\n",
    "        \"W2\": W2,\n",
    "        \"b2\": b2\n",
    "    }\n",
    "\n",
    "    return parameters"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "==============测试initialize_parameters==============\n",
      "W1 = [[ 0.01624345 -0.00611756 -0.00528172]\n",
      " [-0.01072969  0.00865408 -0.02301539]]\n",
      "b1 = [[0.]\n",
      " [0.]]\n",
      "W2 = [[ 0.01744812 -0.00761207]]\n",
      "b2 = [[0.]]\n"
     ]
    }
   ],
   "source": [
    "print(\"==============测试initialize_parameters==============\")\n",
    "parameters = initialize_parameters(3,2,1)\n",
    "print(\"W1 = \" + str(parameters[\"W1\"]))\n",
    "print(\"b1 = \" + str(parameters[\"b1\"]))\n",
    "print(\"W2 = \" + str(parameters[\"W2\"]))\n",
    "print(\"b2 = \" + str(parameters[\"b2\"]))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "outputs": [],
   "source": [
    "def initialize_parameters_deep(layers_dims):\n",
    "    '''\n",
    "    此函数是为了初始化多层网络参数而使用的函数。\n",
    "    参数：\n",
    "        layers_dims - 包含我们网络中每个图层的节点数量的列表\n",
    "\n",
    "    返回：\n",
    "        parameters - 包含参数“W1”，“b1”，...，“WL”，“bL”的字典：\n",
    "                     W1 - 权重矩阵，维度为（layers_dims [1]，layers_dims [1-1]）\n",
    "                     bl - 偏向量，维度为（layers_dims [1]，1）\n",
    "    '''\n",
    "    # 设置随机种子，来控制结果稳定\n",
    "    np.random.seed(3)\n",
    "    parameters = {}  #承载参数\n",
    "    L = len(layers_dims)  #确定隐藏层层数\n",
    "\n",
    "    # 隐藏层层数比传入的参数少一，不包括输入层和输出层\n",
    "    # 随机初始化参数\n",
    "    for l in range(1, L):\n",
    "        parameters['W'+str(l)] = np.random.randn(layers_dims[l], layers_dims[l-1]) / np.sqrt(layers_dims[l-1])\n",
    "        parameters['b'+str(l)] = np.zeros((layers_dims[l], 1))\n",
    "\n",
    "        # 确保数据格式正确\n",
    "        assert(parameters['W'+str(l)].shape == (layers_dims[l], layers_dims[l-1]))\n",
    "        assert(parameters['b'+str(l)].shape == (layers_dims[l], 1))\n",
    "\n",
    "    return parameters"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "==============测试initialize_parameters_deep==============\n",
      "W1 = [[ 0.79989897  0.19521314  0.04315498 -0.83337927 -0.12405178]\n",
      " [-0.15865304 -0.03700312 -0.28040323 -0.01959608 -0.21341839]\n",
      " [-0.58757818  0.39561516  0.39413741  0.76454432  0.02237573]\n",
      " [-0.18097724 -0.24389238 -0.69160568  0.43932807 -0.49241241]]\n",
      "b1 = [[0.]\n",
      " [0.]\n",
      " [0.]\n",
      " [0.]]\n",
      "W2 = [[-0.59252326 -0.10282495  0.74307418  0.11835813]\n",
      " [-0.51189257 -0.3564966   0.31262248 -0.08025668]\n",
      " [-0.38441818 -0.11501536  0.37252813  0.98805539]]\n",
      "b2 = [[0.]\n",
      " [0.]\n",
      " [0.]]\n"
     ]
    }
   ],
   "source": [
    "#测试initialize_parameters_deep\n",
    "print(\"==============测试initialize_parameters_deep==============\")\n",
    "layers_dims = [5,4,3]\n",
    "parameters = initialize_parameters_deep(layers_dims)\n",
    "print(\"W1 = \" + str(parameters[\"W1\"]))\n",
    "print(\"b1 = \" + str(parameters[\"b1\"]))\n",
    "print(\"W2 = \" + str(parameters[\"W2\"]))\n",
    "print(\"b2 = \" + str(parameters[\"b2\"]))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "outputs": [],
   "source": [
    "def linear_forward(A, W, b):\n",
    "    '''\n",
    "    实现前向传播的线性部分。\n",
    "    参数：\n",
    "        A - 来自上一层（或输入数据）的激活，维度为(上一层的节点数量，示例的数量）\n",
    "        W - 权重矩阵，numpy数组，维度为（当前图层的节点数量，前一图层的节点数量）\n",
    "        b - 偏向量，numpy向量，维度为（当前图层节点数量，1）\n",
    "    返回：\n",
    "         Z - 激活功能的输入，也称为预激活参数\n",
    "         cache - 一个包含“A”，“W”和“b”的字典，存储这些变量以有效地计算后向传递\n",
    "    '''\n",
    "    Z = np.dot(W, A) + b  #计算输入\n",
    "    # 确保数据格式正确\n",
    "    assert(Z.shape == (W.shape[0], A.shape[1]))\n",
    "    cache = (A, W, b)\n",
    "\n",
    "    return Z, cache"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "==============测试linear_forward==============\n",
      "Z = [[ 3.26295337 -1.23429987]]\n"
     ]
    }
   ],
   "source": [
    "#测试linear_forward\n",
    "print(\"==============测试linear_forward==============\")\n",
    "A,W,b = testCases.linear_forward_test_case()\n",
    "Z,linear_cache = linear_forward(A,W,b)\n",
    "print(\"Z = \" + str(Z))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "outputs": [],
   "source": [
    "def linear_activation_forward(A_prev, W, b, activation):\n",
    "    '''\n",
    "    实现LINEAR-> ACTIVATION 这一层的前向传播\n",
    "    参数：\n",
    "        A_prev - 来自上一层（或输入层）的激活，维度为(上一层的节点数量，示例数）\n",
    "        W - 权重矩阵，numpy数组，维度为（当前层的节点数量，前一层的大小）\n",
    "        b - 偏向量，numpy阵列，维度为（当前层的节点数量，1）\n",
    "        activation - 选择在此层中使用的激活函数名，字符串类型，【\"sigmoid\" | \"relu\"】\n",
    "    返回：\n",
    "        A - 激活函数的输出，也称为激活后的值\n",
    "        cache - 一个包含“linear_cache”和“activation_cache”的字典，我们需要存储它以有效地计算后向传递\n",
    "    '''\n",
    "    # 区分不同的激活函数\n",
    "    if activation == 'sigmoid':\n",
    "        # 前向传播\n",
    "        Z, linear_cache = linear_forward(A_prev, W, b)\n",
    "        A, activation_cache = sigmoid(Z)\n",
    "    elif activation == 'relu':\n",
    "        Z, linear_cache = linear_forward(A_prev, W, b)\n",
    "        A, activation_cache = relu(Z)\n",
    "\n",
    "    #确保数据格式正确\n",
    "    assert(A.shape == (W.shape[0], A_prev.shape[1]))\n",
    "    cache = (linear_cache, activation_cache)\n",
    "\n",
    "    return A,cache"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "==============测试linear_activation_forward==============\n",
      "sigmoid，A = [[0.96890023 0.11013289]]\n",
      "ReLU，A = [[3.43896131 0.        ]]\n"
     ]
    }
   ],
   "source": [
    "#测试linear_activation_forward\n",
    "print(\"==============测试linear_activation_forward==============\")\n",
    "A_prev, W,b = testCases.linear_activation_forward_test_case()\n",
    "A, linear_activation_cache = linear_activation_forward(A_prev, W, b, activation = \"sigmoid\")\n",
    "print(\"sigmoid，A = \" + str(A))\n",
    "A, linear_activation_cache = linear_activation_forward(A_prev, W, b, activation = \"relu\")\n",
    "print(\"ReLU，A = \" + str(A))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "outputs": [],
   "source": [
    "def L_model_forward(X, parameters):\n",
    "    '''\n",
    "    实现[LINEAR-> RELU] *（L-1） - > LINEAR-> SIGMOID计算前向传播，也就是多层网络的前向传播，为后面每一层都执行LINEAR和ACTIVATION\n",
    "\n",
    "    参数：\n",
    "        X - 数据，numpy数组，维度为（输入节点数量，示例数）\n",
    "        parameters - initialize_parameters_deep（）的输出\n",
    "\n",
    "    返回：\n",
    "        AL - 最后的激活值\n",
    "        caches - 包含以下内容的缓存列表：\n",
    "                 linear_relu_forward（）的每个cache（有L-1个，索引为从0到L-2）\n",
    "                 linear_sigmoid_forward（）的cache（只有一个，索引为L-1）\n",
    "    '''\n",
    "    # 结果存储\n",
    "    caches = []\n",
    "    A = X\n",
    "    L = len(parameters) // 2\n",
    "\n",
    "    # 神经网络结构\n",
    "    # 前面使用relu激活函数，最后一层使用sigmoid函数\n",
    "    for l in range(1, L):\n",
    "        A_prev = A\n",
    "        A, cache = linear_activation_forward(A_prev, parameters['W'+str(l)], parameters['b'+str(l)], 'relu')\n",
    "        caches.append(cache)\n",
    "\n",
    "    AL, cache = linear_activation_forward(A, parameters['W'+str(L)],\\\n",
    "                                         parameters['b'+str(L)], 'sigmoid')\n",
    "    caches.append(cache)\n",
    "\n",
    "    # 确保数据格式正确\n",
    "    assert(AL.shape == (1, X.shape[1]))\n",
    "\n",
    "    return AL, caches"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "==============测试L_model_forward==============\n",
      "AL = [[0.17007265 0.2524272 ]]\n",
      "caches 的长度为 = 2\n"
     ]
    }
   ],
   "source": [
    "#测试L_model_forward\n",
    "print(\"==============测试L_model_forward==============\")\n",
    "X,parameters = testCases.L_model_forward_test_case()\n",
    "AL,caches = L_model_forward(X,parameters)\n",
    "print(\"AL = \" + str(AL))\n",
    "print(\"caches 的长度为 = \" + str(len(caches)))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "outputs": [],
   "source": [
    "def compute_cost(AL, Y):\n",
    "    '''\n",
    "    实施等式（4）定义的成本函数。\n",
    "    参数：\n",
    "        AL - 与标签预测相对应的概率向量，维度为（1，示例数量）\n",
    "        Y - 标签向量（例如：如果不是猫，则为0，如果是猫则为1），维度为（1，数量）\n",
    "    返回：\n",
    "        cost - 交叉熵成本\n",
    "    '''\n",
    "    # 样本数量m\n",
    "    m = Y.shape[1]\n",
    "    cost = -np.sum(np.multiply(np.log(AL), Y)+np.multiply(np.log(1-AL),\\\n",
    "                                    1-Y))/m\n",
    "    # 压缩数据\n",
    "    cost = np.squeeze(cost)\n",
    "    # 确认数据格式\n",
    "    assert(cost.shape == ())\n",
    "\n",
    "    return cost"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "==============测试compute_cost==============\n",
      "cost = 0.414931599615397\n"
     ]
    }
   ],
   "source": [
    "#测试compute_cost\n",
    "print(\"==============测试compute_cost==============\")\n",
    "Y,AL = testCases.compute_cost_test_case()\n",
    "print(\"cost = \" + str(compute_cost(AL, Y)))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "outputs": [],
   "source": [
    "def linear_backward(dZ, cache):\n",
    "    '''\n",
    "    为单层实现反向传播的线性部分（第L层）\n",
    "    参数：\n",
    "         dZ - 相对于（当前第l层的）线性输出的成本梯度\n",
    "         cache - 来自当前层前向传播的值的元组（A_prev，W，b）\n",
    "    返回：\n",
    "         dA_prev - 相对于激活（前一层l-1）的成本梯度，与A_prev维度相同\n",
    "         dW - 相对于W（当前层l）的成本梯度，与W的维度相同\n",
    "         db - 相对于b（当前层l）的成本梯度，与b维度相同\n",
    "    '''\n",
    "    A_prev, W, b = cache\n",
    "    m = A_prev.shape[1]\n",
    "    dW = np.dot(dZ, A_prev.T) / m\n",
    "    db = np.sum(dZ, axis=1, keepdims=True) / m\n",
    "    dA_prev = np.dot(W.T, dZ)\n",
    "\n",
    "    # 确认数据格式正确\n",
    "    assert(dA_prev.shape == A_prev.shape)\n",
    "    assert(dW.shape == W.shape)\n",
    "    assert(db.shape == b.shape)\n",
    "\n",
    "    return dA_prev, dW, db"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "==============测试linear_backward==============\n",
      "dA_prev = [[ 0.51822968 -0.19517421]\n",
      " [-0.40506361  0.15255393]\n",
      " [ 2.37496825 -0.89445391]]\n",
      "dW = [[-0.10076895  1.40685096  1.64992505]]\n",
      "db = [[0.50629448]]\n"
     ]
    }
   ],
   "source": [
    "#测试linear_backward\n",
    "print(\"==============测试linear_backward==============\")\n",
    "dZ, linear_cache = testCases.linear_backward_test_case()\n",
    "dA_prev, dW, db = linear_backward(dZ, linear_cache)\n",
    "print (\"dA_prev = \"+ str(dA_prev))\n",
    "print (\"dW = \" + str(dW))\n",
    "print (\"db = \" + str(db))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "outputs": [],
   "source": [
    "def linear_activation_backward(dA, cache, activation='relu'):\n",
    "    '''\n",
    "    实现LINEAR-> ACTIVATION层的后向传播。\n",
    "\n",
    "    参数：\n",
    "         dA - 当前层l的激活后的梯度值\n",
    "         cache - 我们存储的用于有效计算反向传播的值的元组（值为linear_cache，activation_cache）\n",
    "         activation - 要在此层中使用的激活函数名，字符串类型，【\"sigmoid\" | \"relu\"】\n",
    "    返回：\n",
    "         dA_prev - 相对于激活（前一层l-1）的成本梯度值，与A_prev维度相同\n",
    "         dW - 相对于W（当前层l）的成本梯度值，与W的维度相同\n",
    "         db - 相对于b（当前层l）的成本梯度值，与b的维度相同\n",
    "    '''\n",
    "    # 获取参数\n",
    "    linear_cache, actvation_cache = cache\n",
    "    # 不同的激活函数的导数也不同\n",
    "    if activation == 'relu':\n",
    "        dZ = relu_backward(dA, actvation_cache)\n",
    "        dA_prev, dW, db = linear_backward(dZ, linear_cache)\n",
    "    elif activation == 'sigmoid':\n",
    "        dZ = sigmoid_backward(dA, actvation_cache)\n",
    "        dA_prev, dW, db = linear_backward(dZ, linear_cache)\n",
    "\n",
    "    return dA_prev, dW, db"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "==============测试linear_activation_backward==============\n",
      "sigmoid:\n",
      "dA_prev = [[ 0.11017994  0.01105339]\n",
      " [ 0.09466817  0.00949723]\n",
      " [-0.05743092 -0.00576154]]\n",
      "dW = [[ 0.10266786  0.09778551 -0.01968084]]\n",
      "db = [[-0.05729622]]\n",
      "\n",
      "relu:\n",
      "dA_prev = [[ 0.44090989 -0.        ]\n",
      " [ 0.37883606 -0.        ]\n",
      " [-0.2298228   0.        ]]\n",
      "dW = [[ 0.44513824  0.37371418 -0.10478989]]\n",
      "db = [[-0.20837892]]\n"
     ]
    }
   ],
   "source": [
    "#测试linear_activation_backward\n",
    "print(\"==============测试linear_activation_backward==============\")\n",
    "AL, linear_activation_cache = testCases.linear_activation_backward_test_case()\n",
    "\n",
    "dA_prev, dW, db = linear_activation_backward(AL, linear_activation_cache, activation = \"sigmoid\")\n",
    "print (\"sigmoid:\")\n",
    "print (\"dA_prev = \"+ str(dA_prev))\n",
    "print (\"dW = \" + str(dW))\n",
    "print (\"db = \" + str(db) + \"\\n\")\n",
    "\n",
    "dA_prev, dW, db = linear_activation_backward(AL, linear_activation_cache, activation = \"relu\")\n",
    "print (\"relu:\")\n",
    "print (\"dA_prev = \"+ str(dA_prev))\n",
    "print (\"dW = \" + str(dW))\n",
    "print (\"db = \" + str(db))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "outputs": [],
   "source": [
    "def L_model_backward(AL, Y, caches):\n",
    "    '''\n",
    "    对[LINEAR-> RELU] *（L-1） - > LINEAR - > SIGMOID组执行反向传播，就是多层网络的向后传播\n",
    "\n",
    "    参数：\n",
    "     AL - 概率向量，正向传播的输出（L_model_forward（））\n",
    "     Y - 标签向量（例如：如果不是猫，则为0，如果是猫则为1），维度为（1，数量）\n",
    "     caches - 包含以下内容的cache列表：\n",
    "                 linear_activation_forward（\"relu\"）的cache，不包含输出层\n",
    "                 linear_activation_forward（\"sigmoid\"）的cache\n",
    "\n",
    "    返回：\n",
    "     grads - 具有梯度值的字典\n",
    "              grads [“dA”+ str（l）] = ...\n",
    "              grads [“dW”+ str（l）] = ...\n",
    "              grads [“db”+ str（l）] = ...\n",
    "    '''\n",
    "    # 初始化参数\n",
    "    grads = {}\n",
    "    L = len(caches)\n",
    "    m = AL.shape[1]\n",
    "    Y = Y.reshape(AL.shape)\n",
    "    dAL = -(np.divide(Y, AL)-np.divide(1-Y, 1-AL))\n",
    "\n",
    "    current_cache = caches[L-1]\n",
    "    grads['dA'+str(L)], grads['dW'+str(L)], grads['db'+str(L)] = \\\n",
    "    linear_activation_backward(dAL, current_cache, 'sigmoid')\n",
    "\n",
    "    # 逐层进行反向传播\n",
    "    for l in reversed(range(L-1)):\n",
    "        current_cache = caches[l]  #当前层\n",
    "        dA_prev_temp, dW_temp, db_temp = linear_activation_backward(grads['dA'+\\\n",
    "                                    str(l+2)], current_cache, 'relu')\n",
    "        grads['dA'+str(l+1)] = dA_prev_temp\n",
    "        grads['dW'+str(l+1)] = dW_temp\n",
    "        grads['db'+str(l+1)] = db_temp\n",
    "\n",
    "    return grads"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "==============测试L_model_backward==============\n",
      "dW1 = [[0.41010002 0.07807203 0.13798444 0.10502167]\n",
      " [0.         0.         0.         0.        ]\n",
      " [0.05283652 0.01005865 0.01777766 0.0135308 ]]\n",
      "db1 = [[-0.22007063]\n",
      " [ 0.        ]\n",
      " [-0.02835349]]\n",
      "dA1 = [[ 0.          0.52257901]\n",
      " [ 0.         -0.3269206 ]\n",
      " [ 0.         -0.32070404]\n",
      " [ 0.         -0.74079187]]\n"
     ]
    }
   ],
   "source": [
    "#测试L_model_backward\n",
    "print(\"==============测试L_model_backward==============\")\n",
    "AL, Y_assess, caches = testCases.L_model_backward_test_case()\n",
    "grads = L_model_backward(AL, Y_assess, caches)\n",
    "print (\"dW1 = \"+ str(grads[\"dW1\"]))\n",
    "print (\"db1 = \"+ str(grads[\"db1\"]))\n",
    "print (\"dA1 = \"+ str(grads[\"dA1\"]))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "outputs": [],
   "source": [
    "def update_parameters(parameters, grads, learning_rate):\n",
    "    '''\n",
    "    使用梯度下降更新参数\n",
    "\n",
    "    参数：\n",
    "     parameters - 包含你的参数的字典\n",
    "     grads - 包含梯度值的字典，是L_model_backward的输出\n",
    "\n",
    "    返回：\n",
    "     parameters - 包含更新参数的字典\n",
    "                   参数[“W”+ str（l）] = ...\n",
    "                   参数[“b”+ str（l）] = ...\n",
    "    '''\n",
    "    # 获取隐藏层数\n",
    "    L = len(parameters) // 2\n",
    "\n",
    "    # 逐层进行更新\n",
    "    for l in range(L):\n",
    "        parameters['W'+str(l+1)] = parameters['W'+str(l+1)]-learning_rate*\\\n",
    "        grads[\"dW\" + str(l + 1)]\n",
    "        parameters['b'+str(l+1)] = parameters['b'+str(l+1)]-learning_rate*\\\n",
    "        grads['db'+str(l+1)]\n",
    "\n",
    "    return parameters"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "==============测试update_parameters==============\n",
      "W1 = [[-0.59562069 -0.09991781 -2.14584584  1.82662008]\n",
      " [-1.76569676 -0.80627147  0.51115557 -1.18258802]\n",
      " [-1.0535704  -0.86128581  0.68284052  2.20374577]]\n",
      "b1 = [[-0.04659241]\n",
      " [-1.28888275]\n",
      " [ 0.53405496]]\n",
      "W2 = [[-0.55569196  0.0354055   1.32964895]]\n",
      "b2 = [[-0.84610769]]\n"
     ]
    }
   ],
   "source": [
    "#测试update_parameters\n",
    "print(\"==============测试update_parameters==============\")\n",
    "parameters, grads = testCases.update_parameters_test_case()\n",
    "parameters = update_parameters(parameters, grads, 0.1)\n",
    "\n",
    "print (\"W1 = \"+ str(parameters[\"W1\"]))\n",
    "print (\"b1 = \"+ str(parameters[\"b1\"]))\n",
    "print (\"W2 = \"+ str(parameters[\"W2\"]))\n",
    "print (\"b2 = \"+ str(parameters[\"b2\"]))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "outputs": [],
   "source": [
    "def two_layer_model(X, Y, layers_dims, learning_rate=0.0075, \\\n",
    "        num_iterations=3000, print_cost=False, isPlot=True):\n",
    "    '''\n",
    "    实现一个两层的神经网络，【LINEAR->RELU】 -> 【LINEAR->SIGMOID】\n",
    "    参数：\n",
    "        X - 输入的数据，维度为(n_x，例子数)\n",
    "        Y - 标签，向量，0为非猫，1为猫，维度为(1,数量)\n",
    "        layers_dims - 层数的向量，维度为(n_y,n_h,n_y)\n",
    "        learning_rate - 学习率\n",
    "        num_iterations - 迭代的次数\n",
    "        print_cost - 是否打印成本值，每100次打印一次\n",
    "        isPlot - 是否绘制出误差值的图谱\n",
    "    返回:\n",
    "        parameters - 一个包含W1，b1，W2，b2的字典变量\n",
    "    '''\n",
    "    # 设置随机种子，保证结果可复现\n",
    "    np.random.seed(1)\n",
    "    '''\n",
    "    初始化参数\n",
    "    '''\n",
    "    grads = {}\n",
    "    costs = []\n",
    "    (n_x, n_h, n_y) = layers_dims\n",
    "\n",
    "    parameters = initialize_parameters(n_x, n_h, n_y)\n",
    "    W1 = parameters['W1']\n",
    "    b1 = parameters['b1']\n",
    "    W2 = parameters['W2']\n",
    "    b2 = parameters['b2']\n",
    "\n",
    "    # 开始进行迭代\n",
    "    for i in range(num_iterations):\n",
    "        # 前向传播\n",
    "        A1, cache1 = linear_activation_forward(X, W1, b1, 'relu')\n",
    "        A2, cache2 = linear_activation_forward(A1, W2, b2, 'sigmoid')\n",
    "\n",
    "        # 计算成本\n",
    "        cost = compute_cost(A2, Y)\n",
    "\n",
    "        # 后向传播\n",
    "        # 初始化后向传播\n",
    "        dA2 = -(np.divide(Y, A2) - np.divide(1-Y, 1-A2))\n",
    "\n",
    "        # 后向传播\n",
    "        dA1, dW2, db2 = linear_activation_backward(dA2, cache2, 'sigmoid')\n",
    "        dA0, dW1, db1 = linear_activation_backward(dA1, cache1, 'relu')\n",
    "\n",
    "        # 向后传播的数据保存到grads\n",
    "        grads['dW1'] = dW1\n",
    "        grads['db1'] = db1\n",
    "        grads['dW2'] = dW2\n",
    "        grads['db2'] = db2\n",
    "\n",
    "        # 更新参数\n",
    "        parameters = update_parameters(parameters, grads, learning_rate)\n",
    "        W1 = parameters['W1']\n",
    "        b1 = parameters['b1']\n",
    "        W2 = parameters['W2']\n",
    "        b2 = parameters['b2']\n",
    "\n",
    "        # 打印成本值，如果print_cost=False则被忽略\n",
    "        if i%100 == 0:\n",
    "            #记录成本\n",
    "            costs.append(cost)\n",
    "            if print_cost:\n",
    "                print('第',i,'次迭代，成本值为：', np.squeeze(cost))\n",
    "\n",
    "     #迭代完成，则根据条件进行绘制图\n",
    "    if isPlot:\n",
    "        plt.plot(np.squeeze(costs))\n",
    "        plt.ylabel('cost')\n",
    "        plt.xlabel('iterations (per tens)')\n",
    "        plt.title('Learing rate = '+str(learning_rate))\n",
    "        plt.show()\n",
    "\n",
    "    # 返回参数parameters\n",
    "    return parameters"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "第 0 次迭代，成本值为： 0.6930497356599891\n",
      "第 100 次迭代，成本值为： 0.6464320953428849\n",
      "第 200 次迭代，成本值为： 0.6325140647912676\n",
      "第 300 次迭代，成本值为： 0.6015024920354665\n",
      "第 400 次迭代，成本值为： 0.5601966311605747\n",
      "第 500 次迭代，成本值为： 0.5158304772764732\n",
      "第 600 次迭代，成本值为： 0.4754901313943326\n",
      "第 700 次迭代，成本值为： 0.43391631512257517\n",
      "第 800 次迭代，成本值为： 0.4007977536203885\n",
      "第 900 次迭代，成本值为： 0.35807050113237915\n",
      "第 1000 次迭代，成本值为： 0.3394281538366412\n",
      "第 1100 次迭代，成本值为： 0.305275363619627\n",
      "第 1200 次迭代，成本值为： 0.2749137728213022\n",
      "第 1300 次迭代，成本值为： 0.24681768210614743\n",
      "第 1400 次迭代，成本值为： 0.1985073503746613\n",
      "第 1500 次迭代，成本值为： 0.1744831811255645\n",
      "第 1600 次迭代，成本值为： 0.17080762978094413\n",
      "第 1700 次迭代，成本值为： 0.11306524562164803\n",
      "第 1800 次迭代，成本值为： 0.09629426845937157\n",
      "第 1900 次迭代，成本值为： 0.0834261795972689\n",
      "第 2000 次迭代，成本值为： 0.07439078704319094\n",
      "第 2100 次迭代，成本值为： 0.06630748132267916\n",
      "第 2200 次迭代，成本值为： 0.059193295010381605\n",
      "第 2300 次迭代，成本值为： 0.05336140348560558\n",
      "第 2400 次迭代，成本值为： 0.04855478562877011\n"
     ]
    },
    {
     "data": {
      "text/plain": "<Figure size 432x288 with 1 Axes>",
      "image/png": "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\n"
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "train_set_x_orig , train_set_y , test_set_x_orig , test_set_y , classes = lr_utils.load_dataset()\n",
    "train_x_flatten = train_set_x_orig.reshape(train_set_x_orig.shape[0], -1).T\n",
    "test_x_flatten = test_set_x_orig.reshape(test_set_x_orig.shape[0], -1).T\n",
    "train_x = train_x_flatten / 255\n",
    "train_y = train_set_y\n",
    "test_x = test_x_flatten / 255\n",
    "test_y = test_set_y\n",
    "n_x = 12288\n",
    "n_h = 7\n",
    "n_y = 1\n",
    "layers_dims = (n_x,n_h,n_y)\n",
    "parameters = two_layer_model(train_x, train_set_y, layers_dims = (n_x, n_h, n_y), num_iterations = 2500, print_cost=True,isPlot=True)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "outputs": [],
   "source": [
    "def predict(X, y, parameters):\n",
    "    '''\n",
    "    该函数用于预测L层神经网络的结果，当然也包含两层\n",
    "\n",
    "    参数：\n",
    "     X - 测试集\n",
    "     y - 标签\n",
    "     parameters - 训练模型的参数\n",
    "\n",
    "    返回：\n",
    "     p - 给定数据集X的预测\n",
    "    '''\n",
    "    # 获取样本数量m\n",
    "    m = X.shape[1]\n",
    "    n = len(parameters) // 2 #神经网络的层数\n",
    "    p = np.zeros((1, m))\n",
    "\n",
    "    # 根据参数向前传播\n",
    "    probas, caches = L_model_forward(X, parameters)\n",
    "\n",
    "    # 进行预测\n",
    "    for i in range(0, probas.shape[1]):\n",
    "        # 界限是0.5\n",
    "        if probas[0, i] > 0.5:\n",
    "            p[0, i] = 1\n",
    "        else:\n",
    "            p[0, i] = 0\n",
    "\n",
    "    print(\"准确度为：\"+str(float(np.sum((p==y))/m)))\n",
    "\n",
    "    return p"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "准确度为：1.0\n",
      "准确度为：0.72\n"
     ]
    }
   ],
   "source": [
    "predictions_train = predict(train_x, train_y, parameters)\n",
    "predictions_test = predict(test_x, test_y, parameters)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "outputs": [],
   "source": [
    "def L_layer_model(X, Y, layers_dims, learning_rate=0.0075, num_iterations=3000,\\\n",
    "                 print_cost=False, isPlot=False):\n",
    "    '''\n",
    "    实现一个L层神经网络：[LINEAR-> RELU] *（L-1） - > LINEAR-> SIGMOID。\n",
    "\n",
    "    参数：\n",
    "        X - 输入的数据，维度为(n_x，例子数)\n",
    "        Y - 标签，向量，0为非猫，1为猫，维度为(1,数量)\n",
    "        layers_dims - 层数的向量，维度为(n_y,n_h,···,n_h,n_y)\n",
    "        learning_rate - 学习率\n",
    "        num_iterations - 迭代的次数\n",
    "        print_cost - 是否打印成本值，每100次打印一次\n",
    "        isPlot - 是否绘制出误差值的图谱\n",
    "\n",
    "    返回：\n",
    "     parameters - 模型学习的参数。 然后他们可以用来预测。\n",
    "    '''\n",
    "    # 设置随机数种子，保证结果一致性\n",
    "    np.random.seed(1)\n",
    "    costs = []\n",
    "\n",
    "    # 随机初始化网络参数\n",
    "    parameters = initialize_parameters_deep(layers_dims)\n",
    "\n",
    "    for i in range(0, num_iterations):\n",
    "        # 前向传播\n",
    "        AL, caches = L_model_forward(X, parameters)\n",
    "        # 计算代价函数\n",
    "        cost = compute_cost(AL, Y)\n",
    "        # 反向传播\n",
    "        grads = L_model_backward(AL, Y, caches)\n",
    "        # 梯度下降\n",
    "        parameters = update_parameters(parameters, grads, learning_rate)\n",
    "\n",
    "        #打印成本值，如果print_cost = False则省略\n",
    "        if i%100 == 0:\n",
    "            # 记录成本\n",
    "            costs.append(cost)\n",
    "            # 是否打印成本值\n",
    "            if print_cost:\n",
    "                print(\"第\",i,\"次迭代，成本值为：\", np.squeeze(cost))\n",
    "\n",
    "    # 迭代完成，根据条件绘制图\n",
    "    if isPlot:\n",
    "        plt.plot(np.squeeze(costs))\n",
    "        plt.ylabel('cost')\n",
    "        plt.xlabel('iterations (per tens)')\n",
    "        plt.title('Learning rate = '+str(learning_rate))\n",
    "        plt.show()\n",
    "\n",
    "    return parameters"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "第 0 次迭代，成本值为： 0.715731513413713\n",
      "第 100 次迭代，成本值为： 0.6747377593469114\n",
      "第 200 次迭代，成本值为： 0.6603365433622126\n",
      "第 300 次迭代，成本值为： 0.6462887802148751\n",
      "第 400 次迭代，成本值为： 0.6298131216927774\n",
      "第 500 次迭代，成本值为： 0.606005622926534\n",
      "第 600 次迭代，成本值为： 0.5690041263975134\n",
      "第 700 次迭代，成本值为： 0.519796535043806\n",
      "第 800 次迭代，成本值为： 0.464157167862823\n",
      "第 900 次迭代，成本值为： 0.4084203004829893\n",
      "第 1000 次迭代，成本值为： 0.37315499216069037\n",
      "第 1100 次迭代，成本值为： 0.3057237457304713\n",
      "第 1200 次迭代，成本值为： 0.2681015284774086\n",
      "第 1300 次迭代，成本值为： 0.2387247482767257\n",
      "第 1400 次迭代，成本值为： 0.20632263257914704\n",
      "第 1500 次迭代，成本值为： 0.17943886927493516\n",
      "第 1600 次迭代，成本值为： 0.15798735818801002\n",
      "第 1700 次迭代，成本值为： 0.14240413012273673\n",
      "第 1800 次迭代，成本值为： 0.12865165997884462\n",
      "第 1900 次迭代，成本值为： 0.11244314998151156\n",
      "第 2000 次迭代，成本值为： 0.08505631034959031\n",
      "第 2100 次迭代，成本值为： 0.05758391198600472\n",
      "第 2200 次迭代，成本值为： 0.04456753454691302\n",
      "第 2300 次迭代，成本值为： 0.0380827516659641\n",
      "第 2400 次迭代，成本值为： 0.034410749018394936\n"
     ]
    },
    {
     "data": {
      "text/plain": "<Figure size 432x288 with 1 Axes>",
      "image/png": "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\n"
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "train_set_x_orig , train_set_y , test_set_x_orig , test_set_y , classes = lr_utils.load_dataset()\n",
    "train_x_flatten = train_set_x_orig.reshape(train_set_x_orig.shape[0], -1).T\n",
    "test_x_flatten = test_set_x_orig.reshape(test_set_x_orig.shape[0], -1).T\n",
    "train_x = train_x_flatten / 255\n",
    "train_y = train_set_y\n",
    "test_x = test_x_flatten / 255\n",
    "test_y = test_set_y\n",
    "# 正式训练\n",
    "layers_dims = [12288, 20, 7, 5, 1] #  5-layer model\n",
    "parameters = L_layer_model(train_x, train_y, layers_dims, num_iterations = 2500, print_cost = True,isPlot=True)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "准确度为：0.9952153110047847\n",
      "准确度为：0.78\n"
     ]
    }
   ],
   "source": [
    "pred_train = predict(train_x, train_y, parameters) #训练集\n",
    "pred_test = predict(test_x, test_y, parameters) #测试集"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}